import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;


/**
 * 非复用BIO socket
 */
public class NIOServer {

    public static int PORT = 6660;
    public static String CHARSET = "UTF-8";

//    static List<SocketChannel> linkedList = Collections.synchronizedList(Lists.newArrayList());

    public static void main(String[] args) throws IOException {

        ServerSocketChannel serverSocket = ServerSocketChannel.open();

        serverSocket.configureBlocking(false);

        serverSocket.bind(new InetSocketAddress(PORT));

        // 获取选择器
        Selector selector = Selector.open();


        //将通道注册到选择器上，指定接收“监听通道”事件
        serverSocket.register(selector, SelectionKey.OP_ACCEPT);

        //轮训地获取选择器上已“就绪”的事件--->只要select()>0，说明已就绪
        while (selector.select(1) > 0){

            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

            while (iterator.hasNext()){

                SelectionKey selectionKey = iterator.next();

                //接收事件就绪 -- 开始接收客户端链接
                if(selectionKey.isAcceptable()){

                    SocketChannel socketChannel = serverSocket.accept();

                    //切换成非阻塞状态
                    socketChannel.configureBlocking(false);

                    // 注册到选择器上-->拿到客户端的连接为了读取通道的数据(监听读就绪事件)
                    socketChannel.register(selector, SelectionKey.OP_READ);

                }else if(selectionKey.isReadable()){//读时间 准备就绪

                    //获取当前选择起 为就绪状态的 channel
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();

                    //分配 缓存区空间（卡车）
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);

                    int num;

                    StringBuffer stringBuffer = new StringBuffer();

                    while ((num = socketChannel.read(byteBuffer)) > 0){

                        //切换成 读模式
                        byteBuffer.flip();

                        stringBuffer.append(new String(byteBuffer.array(), Charset.forName(CHARSET)));

                        //切换成 写模式
                        byteBuffer.clear();

                    }
                    System.out.println("接收完成后：" + stringBuffer.toString());

                }

                int state = selectionKey.readyOps();

                System.out.println("state:" + state);

                //移除当前 处理过的 selectKey
                iterator.remove();

            }

        }


//        int loopCount = 0;
//
//        new Thread(()->{
//            try {
//                handleNetByteBuffer();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }).start();
//
//        while (true){
//            loopCount ++;
//            SocketChannel socketChannel = serverSocket.accept();
//            if(socketChannel != null){
//
//                socketChannel.configureBlocking(false);//
//
//                int port = socketChannel.socket().getPort();
//
//                System.out.println("client port:" + port);
//
//                linkedList.add(socketChannel);
//            }else {
//
//                if(loopCount == 1){
//                    System.out.println("socket channel is empty");
//                    System.out.println("loop count:" + loopCount);
//                }
//                continue;
//            }
//        }
    }

//    public static void handleNetByteBuffer() throws IOException {
//
//        ByteBuffer byteBuffer = ByteBuffer.allocate(1024*4);
//
//        while (true){
//            Iterator<SocketChannel> iterator = linkedList.iterator();
//            while (iterator.hasNext()) {//串行 多线程
//                SocketChannel client = iterator.next();
//                int num ;
//                while ((num = client.read(byteBuffer)) > 0){
//
//                    System.out.println("num:" + num);
//                    System.out.println("byteBuffer ---> position ---》》" + byteBuffer.position());
//                    System.out.println("byteBuffer ---> limit ---》》" + byteBuffer.limit());
//                    System.out.println("byteBuffer ---> capacity ---》》" + byteBuffer.capacity());
//
//                    byteBuffer.flip();
//
//                    System.out.println("byteBuffer flip---> position ---》》" + byteBuffer.position());
//                    System.out.println("byteBuffer flip---> limit ---》》" + byteBuffer.limit());
//                    System.out.println("byteBuffer flip---> capacity ---》》" + byteBuffer.capacity());
//
//                    System.out.println("print socket content:" + new String(byteBuffer.array()));
//                    byteBuffer.clear();
//                }
//            }
//        }
//    }
}
